package com.appspot.didit.server;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.appspot.didit.client.workitem.Workitem;
import com.appspot.didit.client.statistic.StatisticResult;
import com.appspot.didit.client.statistic.StatisticService;
import com.appspot.didit.client.tag.Tag;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

@SuppressWarnings("serial")
public class StatisticServiceImpl extends RemoteServiceServlet implements StatisticService {
	
	private static final Logger LOG = Logger.getLogger(WorkitemServiceImpl.class.getName());
	
	public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		resp.sendRedirect("/");
		return;
	}

	@Override
	public StatisticResult getPersonalTimeWithoutProject(Date begin, Date end, ArrayList<Long> tag_ids, Long user_id) {
		
		if(begin.getHours() > 21) {
			end = new Date(end.getTime() + (24-begin.getHours())*60*60*1000L);
    		begin = new Date(begin.getTime() + (24-begin.getHours())*60*60*1000L);
    	}
		
		ArrayList<String> labels = new ArrayList<String>();
		ArrayList<String> labelsForExport = new ArrayList<String>();
		ArrayList<Double> data = new ArrayList<Double>();
		double total = 0.0;
		StatisticResult sr = new StatisticResult();
		ArrayList<Long> workitemId = new ArrayList<Long>();
		PersistenceManager pm = PMF.get().getPersistenceManager();
		try {
			for(Long tag_id:tag_ids) {
				Tag t = pm.getObjectById(Tag.class, tag_id);
				if(t.getItem_id() != null) {
					for(Long id : t.getItem_id()) {
						if(!workitemId.contains(id)) {
							workitemId.add(id);
						}
					}
				}
			}
			Map<String, Double> sum = new HashMap<String, Double>();
			Date date = begin;
			int interval = getInterval(begin, end);
			while(date.getTime() <= end.getTime()) {
				String dateString = UtilServer.getDateString(interval, date);
				labels.add(dateString);
				labelsForExport.add(dateString);
				sum.put(dateString, 0.0);
				date = UtilServer.getNextDate(interval, date);
			}
			String dateStr = UtilServer.getDateString(interval, end);
			if(!sum.containsKey(dateStr)) {
				labels.add(dateStr);
				labelsForExport.add(dateStr);
				sum.put(dateStr, 0.0);
			}
			List<Workitem> results = getWorkitemList(begin, end, user_id, pm);
			for(Workitem wi : results) {
				if(workitemId.contains(wi.getId())) {
					String dateString = UtilServer.getDateString(interval, wi.getDate());
					sum.put(dateString, sum.get(dateString) + wi.getDuration());
					total += wi.getDuration();
				}
			}
			
			for(String key : labels) {
				if(sum.containsKey(key)) {
					data.add(UtilServer.round(sum.get(key)));
				}
			}
			/*
			while(date.getTime() <= end.getTime()) {
				String dateString = UtilServer.getDate(date);
				labels.add(dateString);
				labelsForExport.add(UtilServer.getCompleteDate(date));
				double sum = 0.0;
				for(Workitem wi : workitemList) {
					Date wiDate = wi.getDate();
					if(wiDate.getYear() == date.getYear() && wiDate.getMonth() == date.getMonth() && wiDate.getDate() == date.getDate()) {
						sum += wi.getDuration();
					}
				}
				data.add(sum);
				total += sum;
				date = new Date(date.getTime() + 24 * 60 * 60 * 1000L);
			}
			*/
		} catch (Exception e) {
			e.printStackTrace();
	    	LOG.logp(Level.FINE, "StatisticServiceImpl", "getStatisticResult", e.toString());
	    } finally {
	    	pm.close();
	    }
	    sr.setLabelsForExport(labelsForExport);
		sr.setLabels(labels);
		sr.setData(data);
		sr.setSum(UtilServer.round(total));
		return sr;
	}

	@Override
	public StatisticResult getTeamTime(Date begin, Date end, Long tag_id) {
		if(begin.getHours() > 21) {
			end = new Date(end.getTime() + (24-begin.getHours())*60*60*1000L);
    		begin = new Date(begin.getTime() + (24-begin.getHours())*60*60*1000L);
    	}
		begin.setDate(1);
		ArrayList<String> labels = new ArrayList<String>();
		ArrayList<String> labelsForExport = new ArrayList<String>();
		ArrayList<Double> data = new ArrayList<Double>();
		ArrayList<Long> workitemId = new ArrayList<Long>();
		ArrayList<Workitem> workitemList = new ArrayList<Workitem>();
		double total = 0.0;
		StatisticResult sr = new StatisticResult();
		PersistenceManager pm = PMF.get().getPersistenceManager();
		try {
			Tag t = pm.getObjectById(Tag.class, tag_id);
			Date projectBegin = t.getProjectBegin();
			ArrayList<Long> tag_ids = new ArrayList<Long>();
			if(t.getRelatedTags() != null) {
				for(Long id : t.getRelatedTags()) {
					tag_ids.add(id);
				}
			}
			tag_ids.add(tag_id);
			for(Long id : tag_ids) {
				t = pm.getObjectById(Tag.class, id);
				if(t.getItem_id() != null) {
					for(Long wid : t.getItem_id()) {
						workitemId.add(wid);
					}
				}
			}
			Date date = begin;
			while(date.before(end)) {
				String dateString = UtilServer.getMonthWithCompleteYear(date);
				labels.add(dateString);
				labelsForExport.add(dateString);
				data.add(0.0);
				date.setMonth(date.getMonth() + 1);
			}
			
			Query query = pm.newQuery(Workitem.class, ":p.contains(id)");
			List<Workitem> results = (List<Workitem>) query.execute(workitemId);
			for(Workitem wi : results) {
				Date wiDate = wi.getDate();
				String dateString = UtilServer.getMonthWithCompleteYear(wiDate);
				int index = labels.indexOf(dateString);
				if(index > -1) {
					data.set(index, data.get(index) + wi.getDuration());
					total += wi.getDuration();
				}
			}
			
		} catch (Exception e) {
			e.printStackTrace();
	    	LOG.logp(Level.FINE, "StatisticServiceImpl", "getStatisticResult", e.toString());
	    } finally {
	    	pm.close();
	    }
	    sr.setLabelsForExport(labelsForExport);
		sr.setLabels(labels);
		sr.setData(data);
		sr.setSum(UtilServer.round(total));
		return sr;
	}
	
	@Override
	public StatisticResult getProjectProgress(Date begin, Date end, Long tag_id) {
		if(begin.getHours() > 21) {
			end = new Date(end.getTime() + (24-begin.getHours())*60*60*1000L);
    		begin = new Date(begin.getTime() + (24-begin.getHours())*60*60*1000L);
    	}
		Date today = new Date();
		ArrayList<String> labels = new ArrayList<String>();
		ArrayList<Double> data = new ArrayList<Double>();
		ArrayList<Long> workitemId = new ArrayList<Long>();
		ArrayList<Workitem> workitemList = new ArrayList<Workitem>();
		StatisticResult sr = new StatisticResult();
		PersistenceManager pm = PMF.get().getPersistenceManager();
		try {
			Tag t = pm.getObjectById(Tag.class, tag_id);
			Date projectBegin = t.getProjectBegin();
			ArrayList<Long> tag_ids = new ArrayList<Long>();
			if(t.getRelatedTags() != null) {
				for(Long id : t.getRelatedTags()) {
					tag_ids.add(id);
				}
			}
			tag_ids.add(tag_id);
			for(Long id : tag_ids) {
				t = pm.getObjectById(Tag.class, id);
				if(t.getItem_id() != null) {
					for(Long wid : t.getItem_id()) {
						workitemId.add(wid);
					}
				}
			}
			Query query = pm.newQuery(Workitem.class, ":p.contains(id)");
			List<Workitem> results = (List<Workitem>) query.execute(workitemId);
			for(Workitem wi : results) {
				if(wi.getDate().getTime() >= projectBegin.getTime() && wi.getDate().getTime() <= end.getTime()) {
					workitemList.add(wi);
				}
			}
			Date date = new Date(begin.getTime());
			String dateString;
			boolean heute = false;
			double sum;
			while(date.before(end)) {
				if(today.getYear() == date.getYear() && today.getMonth() == date.getMonth()) {
					labels.add("heute");
					heute = true;
				} else if(date.equals(begin)) { //|| (today.getYear() == date.getYear() && today.getMonth() == date.getMonth() + 1)|| (today.getYear() == date.getYear() && today.getMonth() == date.getMonth() - 1)) {
					dateString = UtilServer.getCompleteDate(date);
					labels.add(dateString);
				} else {
					labels.add("");
				}
				sum = 0.0;
				if(date.before(today)) {
					for(Workitem wi : workitemList) {
						Date wiDate = wi.getDate();
						if(wiDate.getTime() <= date.getTime() || heute) {
							sum += wi.getDuration();	
						}
					}
					data.add(sum);
				}
				heute = false;
				date.setMonth(date.getMonth() + 1);
			}
			if(end.getDate() != 1 && end.before(today)) {
				sum = 0.0;
				for(Workitem wi : workitemList) {
					Date wiDate = wi.getDate();
					if(wiDate.getTime() <= end.getTime()) {
						sum += wi.getDuration();	
					}
				}
				data.add(UtilServer.round(sum));
			}
			dateString = UtilServer.getCompleteDate(end);
			labels.add(dateString);
		} catch (Exception e) {
			e.printStackTrace();
	    	LOG.logp(Level.FINE, "StatisticServiceImpl", "getStatisticResult", e.toString());
	    } finally {
	    	pm.close();
	    }
		sr.setLabels(labels);
		sr.setData(data);
		return sr;
	}
	
	@Override
	public StatisticResult getPersonalTimeByProject(Date begin, Date end, 
			ArrayList<Long> tag_ids, Long user_id) {
		if(begin.getHours() > 21) {
			end = new Date(end.getTime() + (24-begin.getHours())*60*60*1000L);
    		begin = new Date(begin.getTime() + (24-begin.getHours())*60*60*1000L);
    	}
		ArrayList<String> labels = new ArrayList<String>();
		ArrayList<Double> data = new ArrayList<Double>();
		double total = 0.0;
		StatisticResult sr = new StatisticResult();
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Map<Long, String> workitems = new HashMap<Long, String>();
		Map<String, Double> sum = new HashMap<String, Double>();
		try {
			for(Long tag_id:tag_ids) {
				Tag t = pm.getObjectById(Tag.class, tag_id);
				String tagname = t.getTagname();
				if(t.getItem_id() != null) {
					for(Long id : t.getItem_id()) {
						if(!workitems.containsKey(id)) {
							workitems.put(id, tagname);
						} else {
							String newValue = workitems.get(id) + " " + tagname;
							workitems.put(id, newValue);
						}
					}
				}
			}
			List<Workitem> results = getWorkitemList(begin, end, user_id, pm);
			if(workitems.keySet().size() < results.size()) {
				for(Long id : workitems.keySet()) {
					Workitem wi = pm.getObjectById(Workitem.class, id);
					Date wiDate = wi.getDate();
					if(wiDate.getTime() >= begin.getTime() && wiDate.getTime() <= end.getTime()) {
						String label = workitems.get(id);
						total += wi.getDuration();
						if(!sum.containsKey(label)) {
							sum.put(label, wi.getDuration());
						} else {
							Double newValue = sum.get(label) + wi.getDuration();
							sum.put(label, newValue);
						}
					}
				}
			} else {
				for(Workitem wi : results) {
					if(workitems.containsKey(wi.getId())) {
						Date wiDate = wi.getDate();
						String label = workitems.get(wi.getId());
						total += wi.getDuration();
						if(!sum.containsKey(label)) {
							sum.put(label, wi.getDuration());
						} else {
							Double newValue = sum.get(label) + wi.getDuration();
							sum.put(label, newValue);
						}
					}
				}
			}
			
			for(String label : sum.keySet()) {
				labels.add(label);
				data.add(UtilServer.round(sum.get(label)));
			}
		} catch (Exception e) {
	    	LOG.logp(Level.FINE, "StatisticServiceImpl", "getStatisticResult", e.toString());
	    } finally {
	    	pm.close();
	    }
		sr.setLabels(labels);
		sr.setData(data);
		sr.setSum(UtilServer.round(total));
		return sr;
	}

	private List<Workitem> getWorkitemList(Date begin, Date end, Long user_id,
			PersistenceManager pm) {
		Query query = pm.newQuery(Workitem.class,
		        "user_id == " + user_id +
		        " && date >= begin  && date <= end" );
		query.declareImports("import java.util.Date;");
		query.declareParameters("Date begin, Date end");
		List<Workitem> results = (List<Workitem>) query.execute(begin, end);
		return results;
	}

	@Override
	public StatisticResult getPersonalTimeByWeekday(Date begin, Date end,
			ArrayList<Long> tag_ids, Long user_id) {
		if(begin.getHours() > 21) {
			end = new Date(end.getTime() + (24-begin.getHours())*60*60*1000L);
    		begin = new Date(begin.getTime() + (24-begin.getHours())*60*60*1000L);
    	}
		ArrayList<Double> data = new ArrayList<Double>();
		double total = 0.0;
		StatisticResult sr = new StatisticResult();
		PersistenceManager pm = PMF.get().getPersistenceManager();
		double[] sum = new double[7];
		for(int i = 0; i < 7; i++) {
			sum[i] = 0;
		}
		ArrayList<Long> workitem_ids = new ArrayList<Long>();
		try {
			for(Long tag_id:tag_ids) {
				Tag t = pm.getObjectById(Tag.class, tag_id);
				if(t.getItem_id() != null) {
					for(Long id : t.getItem_id()) {
						if(!workitem_ids.contains(id)) {
							/*Workitem wi = pm.getObjectById(Workitem.class, id);
							Date date = wi.getDate();
							if(date.getTime() >= begin.getTime() && date.getTime() <= end.getTime()) {
								sum[date.getDay()] += wi.getDuration();
							}*/
							workitem_ids.add(id);
						}
					}
				}
			}
			
			List<Workitem> results = getWorkitemList(begin, end, user_id, pm);
			if(workitem_ids.size() < results.size()) {
				for(Long id : workitem_ids) {
					Workitem wi = pm.getObjectById(Workitem.class, id);
					Date date = wi.getDate();
					if(date.getTime() >= begin.getTime() && date.getTime() <= end.getTime()) {
						sum[date.getDay()] += wi.getDuration();
					}
				}
			} else {
				for(Workitem wi : results) {
					if(workitem_ids.contains(wi.getId())) {
						sum[wi.getDate().getDay()] += wi.getDuration();
					}
				}
			}
			
			
			for(int i = 0; i < 7; i++) {
				total += sum[i];
				data.add(UtilServer.round(sum[i]));
			}
		} catch (Exception e) {
	    	LOG.logp(Level.FINE, "StatisticServiceImpl", "getStatisticResult", e.toString());
	    } finally {
	    	pm.close();
	    }
		sr.setLabels(null);
		sr.setData(data);
		sr.setSum(UtilServer.round(total));
		return sr;
	}

	@Override
	public StatisticResult getPersonalTimeWithProject(Date begin, Date end,
			ArrayList<Long> tag_ids, Long user_id) {
		if(begin.getHours() > 21) {
			end = new Date(end.getTime() + (24-begin.getHours())*60*60*1000L);
    		begin = new Date(begin.getTime() + (24-begin.getHours())*60*60*1000L);
    	}
		ArrayList<String> labels = new ArrayList<String>();
		ArrayList<String> labelsForExport = new ArrayList<String>();
		double total = 0.0;
		StatisticResult sr = new StatisticResult();
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Map<Long, String> workitems = new HashMap<Long, String>();
		ArrayList<Workitem> workitemList = new ArrayList<Workitem>();
		Map<String, Map<String, Double>> data1 = new HashMap<String, Map<String, Double>>();
		Map<String, Double> keys = new HashMap<String, Double>();
		
		try {
			for(Long tag_id:tag_ids) {
				Tag t = pm.getObjectById(Tag.class, tag_id);
				String tagname = t.getTagname();
				if(t.getItem_id() != null) {
					for(Long id : t.getItem_id()) {
						if(!workitems.containsKey(id)) {
							workitems.put(id, tagname);
						} else {
							String newValue = workitems.get(id) + " " + tagname;
							workitems.put(id, newValue);
						}
					}
				}
			}
			
			List<Workitem> results = getWorkitemList(begin, end, user_id, pm);
			
			for(Workitem wi : results) {
				if(workitems.containsKey(wi.getId())) {
					workitemList.add(wi);
				}
			}
			
			Date date = begin;
			int interval = getInterval(begin, end);
			
			while(date.getTime() <= end.getTime()) {	
				String dateString = UtilServer.getDateString(interval, date);
				labels.add(dateString);
				labelsForExport.add(dateString);		
				Map<String, Double> sum = new HashMap<String, Double>();
				for(Workitem wi : workitemList) {
					Date wiDate = wi.getDate();
					if(UtilServer.getDateString(interval, date).equals(UtilServer.getDateString(interval, wiDate))) {
						String label = workitems.get(wi.getId());
						total += wi.getDuration();
						if(!sum.containsKey(label)) {
							sum.put(label, wi.getDuration());
						} else {
							Double newValue = sum.get(label) + wi.getDuration();
							sum.put(label, UtilServer.round(newValue));
						}
						if(!keys.containsKey(label)) {
							keys.put(label, wi.getDuration());
						} else {
							Double newValue = keys.get(label) + wi.getDuration();
							keys.put(label, UtilServer.round(newValue));
						}
					}
				}
				data1.put(dateString, sum);
				System.out.println(UtilServer.getDateString(interval, date));
				date = UtilServer.getNextDate(interval, date);
			}
			if(UtilServer.getDateString(interval, date).equals(UtilServer.getDateString(interval, end))) {
				String dateString = UtilServer.getDateString(interval, date);
				Map<String, Double> sum = new HashMap<String, Double>();
				labels.add(dateString);
				labelsForExport.add(dateString);	
				for(Workitem wi : workitemList) {
					Date wiDate = wi.getDate();
					if(UtilServer.getDateString(interval, date).equals(UtilServer.getDateString(interval, wiDate))) {
						String label = workitems.get(wi.getId());
						total += wi.getDuration();
						if(!sum.containsKey(label)) {
							sum.put(label, wi.getDuration());
						} else {
							Double newValue = sum.get(label) + wi.getDuration();
							sum.put(label, UtilServer.round(newValue));
						}
						if(!keys.containsKey(label)) {
							keys.put(label, wi.getDuration());
						} else {
							Double newValue = keys.get(label) + wi.getDuration();
							keys.put(label, UtilServer.round(newValue));
						}
					}
				}
				data1.put(dateString, sum);
			}
			
		} catch (Exception e) {
	    	LOG.logp(Level.FINE, "StatisticServiceImpl", "getStatisticResult", e.toString());
	    } finally {
	    	pm.close();
	    }
	    sr.setLabelsForExport(labelsForExport);
		sr.setLabels(labels);
		sr.setComplexData(data1);
		sr.setKeys(keys);
		sr.setSum(UtilServer.round(total));
		return sr;
	}

	private int getInterval(Date begin, Date end) {
		int interval = 0;
		if(end.getTime() - begin.getTime() < 10 * UtilServer.MilisecondsPerDay) {
			interval = 0;
		} else if(end.getTime() - begin.getTime() < 6 * UtilServer.MilisecondsPerWeek) {
			interval = 1;
		} else {
			interval = 2;
		}
		return interval;
	}
	
	public String getExportToken1(Date begin, Date end, ArrayList<Long> tag_ids, Long user_id) {
		String token = "";
		String csvData = "Datum;Projekte;Summe;\n";
		StatisticResult sr = getPersonalTimeWithoutProject(begin, end, tag_ids, user_id);
		ArrayList<String> labels = sr.getLabelsForExport();
		ArrayList<Double> data = sr.getData();
		String tagString = "";
		PersistenceManager pm = PMF.get().getPersistenceManager();
		try {
			for(Long tag_id:tag_ids) {
				Tag t = pm.getObjectById(Tag.class, tag_id);
				tagString += " " + t.getTagname();
			}
			tagString = tagString.substring(1);
		} catch (Exception e) {
	    	LOG.logp(Level.FINE, "StatisticServiceImpl", "getStatisticResult", e.toString());
	    } finally {
	    	pm.close();
	    }
		for(int i = 0; i < sr.getLabels().size(); i++) {
			if(data.get(i)>0) {
				csvData += labels.get(i) + ";" + tagString + ";" + data.get(i) + ";\n";
			}
		}
		csvData += "Summe:;" + sr.getSum() +" Stunden;\n";
		token = System.currentTimeMillis()+""+Math.round(Math.random()) + "";
        getThreadLocalRequest().getSession().setAttribute("export_" + token, csvData);
		return token;
	}
	
	public String getExportToken2(Date begin, Date end, ArrayList<Long> tag_ids, Long user_id) {
		String token = "";
		String csvData = "Datum;Projekte;Summe;\n";
		StatisticResult sr = getPersonalTimeWithProject(begin, end, tag_ids, user_id);
		ArrayList<String> labels = sr.getLabelsForExport();
		Map<String, Map<String, Double>> complexData = sr.getComplexData();
		for(int i = 0; i < labels.size(); i++) {
			Map<String, Double> data = complexData.get(sr.getLabels().get(i));
        	for(String s : data.keySet()) {
        		if(data.get(s)>0) {
    				csvData += labels.get(i) + ";" + s + ";" + data.get(s) + ";\n";
    			}
        	}
		}
		csvData += "Summe:;" + sr.getSum() +" Stunden;\n";
		token = System.currentTimeMillis()+""+Math.round(Math.random()) + "";
        getThreadLocalRequest().getSession().setAttribute("export_" + token, csvData);
		return token;
	}
	
	public String getExportToken3(Date begin, Date end, Long tag_id) {
		String token = "";
		String csvData = "Datum;Projekte;Summe;\n";
		StatisticResult sr = getTeamTime(begin, end, tag_id);
		ArrayList<String> labels = sr.getLabelsForExport();
		ArrayList<Double> data = sr.getData();
		String tagString = "";
		PersistenceManager pm = PMF.get().getPersistenceManager();
		try {
			Tag t = pm.getObjectById(Tag.class, tag_id);
			tagString = t.getTagname();
		} catch (Exception e) {
	    	LOG.logp(Level.FINE, "StatisticServiceImpl", "getStatisticResult", e.toString());
	    } finally {
	    	pm.close();
	    }
		for(int i = 0; i < sr.getLabelsForExport().size(); i++) {
			if(data.get(i)>0) {
				csvData += labels.get(i) + ";" + tagString + ";" + data.get(i) + ";\n";
			}
		}
		csvData += "Summe:;" + sr.getSum() +" Stunden;\n";
		token = System.currentTimeMillis()+""+Math.round(Math.random()) + "";
        getThreadLocalRequest().getSession().setAttribute("export_" + token, csvData);
		return token;
	}

	@Override
	public String getStundenzettel(Date begin, Date end,
			ArrayList<Long> tag_ids, Long user_id) {
		String token = "";
		String csvData = "Datum;Beschreibung;Projekte;Dauer;\n";
		ArrayList<Long> workitems = new ArrayList<Long>();
		double sum = 0.0;
		PersistenceManager pm = PMF.get().getPersistenceManager();
		try {
			for(Long tag_id:tag_ids) {
				Tag t = pm.getObjectById(Tag.class, tag_id);
				for(Long id : t.getItem_id()) {
					if(!workitems.contains(id)) {
						workitems.add(id);
					}
				}
			}
			String sql = "SELECT FROM " + Workitem.class.getName() + " where user_id == " + user_id + " order by date";
			//Query query = pm.newQuery(Workitem.class, ":p.contains(id)");
			//query.setOrdering("date");
			//List<Workitem> results = (List<Workitem>) query.execute(workitems);
			List<Workitem> results = (List<Workitem>) pm.newQuery(sql).execute();
			for(int i=0; i < results.size(); i++) {
				Workitem wi = results.get(i);
				if(workitems.contains(wi.getId()) && wi.getDate().after(begin) && wi.getDate().before(end)) {
					System.out.println(wi.getDate());
					sum += wi.getDuration();
					csvData += UtilServer.getCompleteDate(wi.getDate()) + ";" + wi.getDescription() + ";" + wi.getTagString() + ";" + wi.getDuration() + ";\n";
				}
			}
			csvData += "Summe:;" + sum +" Stunden;\n";
		} catch (Exception e) {
	    	LOG.logp(Level.FINE, "StatisticServiceImpl", "getStatisticResult", e.toString());
	    } finally {
	    	pm.close();
	    }
		token = System.currentTimeMillis()+""+Math.round(Math.random()) + "";
        getThreadLocalRequest().getSession().setAttribute("export_" + token, csvData);
		return token;
	}

	@Override
	public StatisticResult getTeamTimeInDetail(Date begin, Date end, Long tag_id) {
		/*
		 * ArrayList<String> labels = new ArrayList<String>();
		ArrayList<String> labelsForExport = new ArrayList<String>();
		double total = 0.0;
		StatisticResult sr = new StatisticResult();
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Map<Long, String> workitems = new HashMap<Long, String>();
		ArrayList<Workitem> workitemList = new ArrayList<Workitem>();
		Map<String, Map<String, Double>> data1 = new HashMap<String, Map<String, Double>>();
		Map<String, Double> keys = new HashMap<String, Double>();
		
		try {
			for(Long tag_id:tag_ids) {
				Tag t = pm.getObjectById(Tag.class, tag_id);
				String tagname = t.getTagname();
				if(t.getItem_id() != null) {
					for(Long id : t.getItem_id()) {
						if(!workitems.containsKey(id)) {
							workitems.put(id, tagname);
						} else {
							String newValue = workitems.get(id) + " " + tagname;
							workitems.put(id, newValue);
						}
					}
				}
			}
			
			List<Workitem> results = getWorkitemList(begin, end, user_id, pm);
			
			for(Workitem wi : results) {
				if(workitems.containsKey(wi.getId())) {
					workitemList.add(wi);
				}
			}
			
			Date date = begin;
			int interval = getInterval(begin, end);
			
			while(date.getTime() <= end.getTime()) {	
				String dateString = UtilServer.getDateString(interval, date);
				labels.add(dateString);
				labelsForExport.add(dateString);		
				Map<String, Double> sum = new HashMap<String, Double>();
				for(Workitem wi : workitemList) {
					Date wiDate = wi.getDate();
					if(UtilServer.getDateString(interval, date).equals(UtilServer.getDateString(interval, wiDate))) {
						String label = workitems.get(wi.getId());
						total += wi.getDuration();
						if(!sum.containsKey(label)) {
							sum.put(label, wi.getDuration());
						} else {
							Double newValue = sum.get(label) + wi.getDuration();
							sum.put(label, UtilServer.round(newValue));
						}
						if(!keys.containsKey(label)) {
							keys.put(label, wi.getDuration());
						} else {
							Double newValue = keys.get(label) + wi.getDuration();
							keys.put(label, UtilServer.round(newValue));
						}
					}
				}
				data1.put(dateString, sum);
				System.out.println(UtilServer.getDateString(interval, date));
				date = UtilServer.getNextDate(interval, date);
			}
			if(UtilServer.getDateString(interval, date).equals(UtilServer.getDateString(interval, end))) {
				String dateString = UtilServer.getDateString(interval, date);
				Map<String, Double> sum = new HashMap<String, Double>();
				labels.add(dateString);
				labelsForExport.add(dateString);	
				for(Workitem wi : workitemList) {
					Date wiDate = wi.getDate();
					if(UtilServer.getDateString(interval, date).equals(UtilServer.getDateString(interval, wiDate))) {
						String label = workitems.get(wi.getId());
						total += wi.getDuration();
						if(!sum.containsKey(label)) {
							sum.put(label, wi.getDuration());
						} else {
							Double newValue = sum.get(label) + wi.getDuration();
							sum.put(label, UtilServer.round(newValue));
						}
						if(!keys.containsKey(label)) {
							keys.put(label, wi.getDuration());
						} else {
							Double newValue = keys.get(label) + wi.getDuration();
							keys.put(label, UtilServer.round(newValue));
						}
					}
				}
				data1.put(dateString, sum);
			}
			
		} catch (Exception e) {
	    	LOG.logp(Level.FINE, "StatisticServiceImpl", "getStatisticResult", e.toString());
	    } finally {
	    	pm.close();
	    }
	    sr.setLabelsForExport(labelsForExport);
		sr.setLabels(labels);
		sr.setComplexData(data1);
		sr.setKeys(keys);
		sr.setSum(UtilServer.round(total));
		return sr;
		 */
		
		if(begin.getHours() > 21) {
			end = new Date(end.getTime() + (24-begin.getHours())*60*60*1000L);
    		begin = new Date(begin.getTime() + (24-begin.getHours())*60*60*1000L);
    	}
		begin.setDate(1);
		ArrayList<String> labels = new ArrayList<String>();
		ArrayList<String> labelsForExport = new ArrayList<String>();
		ArrayList<Double> data = new ArrayList<Double>();
		ArrayList<Long> workitemId = new ArrayList<Long>();
		ArrayList<Workitem> workitemList = new ArrayList<Workitem>();
		Map<String, Map<String, Double>> data1 = new HashMap<String, Map<String, Double>>();
		Map<String, Double> keys = new HashMap<String, Double>();
		Map<Long, String> usernames = new HashMap<Long, String>();
		
		double total = 0.0;
		StatisticResult sr = new StatisticResult();
		PersistenceManager pm = PMF.get().getPersistenceManager();
		try {
			Tag t = pm.getObjectById(Tag.class, tag_id);
			Date projectBegin = t.getProjectBegin();
			ArrayList<Long> tag_ids = new ArrayList<Long>();
			if(t.getRelatedTags() != null) {
				for(Long id : t.getRelatedTags()) {
					tag_ids.add(id);
				}
			}
			tag_ids.add(tag_id);
			for(Long id : tag_ids) {
				t = pm.getObjectById(Tag.class, id);
				keys.put(t.getCreatorname(), 0.0);
				usernames.put(t.getCreator_id(), t.getCreatorname());
				if(t.getItem_id() != null) {
					for(Long wid : t.getItem_id()) {
						workitemId.add(wid);
					}
				}
			}
			
			Date date = begin;
			while(date.before(end)) {
				String dateString = UtilServer.getMonthWithCompleteYear(date);
				labels.add(dateString);
				labelsForExport.add(dateString);
				data1.put(dateString, new HashMap<String, Double>());
				date.setMonth(date.getMonth() + 1);
			}
			
			Query query = pm.newQuery(Workitem.class, ":p.contains(id)");
			List<Workitem> results = (List<Workitem>) query.execute(workitemId);
			for(Workitem wi : results) {
				Date wiDate = wi.getDate();
				String dateString = UtilServer.getMonthWithCompleteYear(wiDate);
				int index = labels.indexOf(dateString);
				if(index > -1) {
					String creatorname = usernames.get(wi.getUser_id());
					keys.put(creatorname, keys.get(creatorname) + wi.getDuration());
					Map<String, Double> sum;
					if(data1.get(dateString) != null) { 
						sum = data1.get(dateString);
						if(sum.containsKey(creatorname)) {
							sum.put(creatorname, sum.get(creatorname)+wi.getDuration());
						} else {
							sum.put(creatorname, wi.getDuration());
						}
					} else {
						sum = new HashMap<String, Double>();
						sum.put(creatorname, wi.getDuration());
					}
					data1.put(dateString, sum);
				}
			}
			
		} catch (Exception e) {
			e.printStackTrace();
	    	LOG.logp(Level.FINE, "StatisticServiceImpl", "getStatisticResult", e.toString());
	    } finally {
	    	pm.close();
	    }
	    sr.setLabelsForExport(labelsForExport);
		sr.setLabels(labels);
		sr.setData(data);
		sr.setComplexData(data1);
		sr.setKeys(keys);
		sr.setSum(UtilServer.round(total));
		return sr;
	}
}


